﻿define([
    'Xjs/core/util'
],
function (util) {
    'use strict';

    return {

        // Gets the node element by its id
        getById: function (id, node) {
            return (node || document).getElementById(id);
        },

        // Gets the node element by its tag name. It might return an array of elements
        getByTagName: function (name, node) {
            return (node || document).getElementsByTagName(name);
        },

        // Gets the body of the html document
        getBody: function () {
            return this.getByTagName('body')[0];
        },

        // Appends a node or html to an existing node
        append: function (node, child) {

            if (util.isString(node)) {
                node = this.getById(node);
            }

            if (util.isDomNode(child)) {
                node.appendChild(child);
            }
            else {
                var n = document.createElement('div'); // TODO: Research how to create an element from html without wrappers
                n.innerHTML = child;
                node.appendChild(n);
            }
        },

        setValue: function (el, val) {
            if (util.isString(el)) {
                el = this.getById(el);
            }

            el.value = val;
        },

        getValue: function (el) {
            if (util.isString(el)) {
                el = this.getById(el);
            }

            return el.value;
        },

        // Shows the element identified by its id
        show: function (el) {
            if (util.isString(el)) {
                el = this.getById(el);
            }

            el.style.display = '';
        },

        // Hides the element
        hide: function (el) {
            if (util.isString(el)) {
                el = this.getById(el);
            }

            el.style.display = 'none';
        },

        setVisible: function (el, visible) {
            if (util.isString(el)) {
                el = this.getById(el);
            }

            if (visible === false) {
                el.style.visibility = 'hidden';
            }
            else {
                el.style.visibility = 'visible';
            }
        },

        // Enables the element
        enable: function (el) {
            if (util.isString(el)) {
                el = this.getById(el);
            }

            el.disabled = false;
        },

        // Disables the element
        disable: function (el) {
            if (util.isString(el)) {
                el = this.getById(el);
            }

            el.disabled = true;
        },

        // Returns true if the element has the class, otherwise it returns false
        hasClass: function (el, cls) {
            if (util.isString(el)) {
                el = this.getById(el);
            }

            return el.classList.contains(cls);
        },

        // Adds the class to the element
        addClass: function (el, cls) {
            if (util.isString(el)) {
                el = this.getById(el);
            }

            if (!el.classList.contains(cls)) {
                el.classList.add(cls);
            }
        },

        // Removes the class from the element
        removeClass: function (el, cls) {
            if (util.isString(el)) {
                el = this.getById(el);
            }

            if (el.classList.contains(cls)) {
                el.classList.remove(cls);
            }
        },

        replaceClass: function (el, p, n) {
            if (util.isString(el)) {
                el = this.getById(el);
            }

            if (el.classList.contains(p)) {
                el.classList.remove(p);
            }

            if (!el.classList.contains(n)) {
                el.classList.add(n);
            }
        },

        toggleClass: function (el, cls) {
            if (util.isString(el)) {
                el = this.getById(el);
            }

            el.classList.toggle(cls);
        },

        // Sets the left position of the element
        setLeft: function (el, pos, units) {
            if (util.isString(el)) {
                el = this.getById(el);
            }

            el.style.left = pos + (units ? units : 'px');
        },

        // Sets the right position of the element
        setRight: function (el, pos, units) {
            if (util.isString(el)) {
                el = this.getById(el);
            }

            el.style.right = pos + (units ? units : 'px');
        },

        // Sets the top position of the element
        setTop: function (el, pos, units) {
            if (util.isString(el)) {
                el = this.getById(el);
            }

            el.style.top = pos + (units ? units : 'px');
        },

        // Sets the bottom position of the element
        setBottom: function (el, pos, units) {
            if (util.isString(el)) {
                el = this.getById(el);
            }

            el.style.bottom = pos + (units ? units : 'px');
        },

        left: function (el) {
            if (util.isString(el)) {
                el = this.getById(el);
            }

            return el.offsetLeft;
        },

        right: function (el) {
            if (util.isString(el)) {
                el = this.getById(el);
            }

            return el.offsetLeft + el.offsetWidth;
        },

        top: function (el) {
            if (util.isString(el)) {
                el = this.getById(el);
            }

            return el.offsetTop;
        },

        bottom: function (el) {
            if (util.isString(el)) {
                el = this.getById(el);
            }

            return el.offsetTop + el.offsetHeight;
        },

        width: function (el) {
            if (util.isString(el)) {
                el = this.getById(el);
            }

            return el.offsetWidth;
        },

        height: function (el) {
            if (util.isString(el)) {
                el = this.getById(el);
            }

            return el.offsetHeight;
        },

        move: function (el, x, y, units) {
            if (util.isString(el)) {
                el = this.getById(el);
            }

            el.style.left = x + (units ? units : 'px');
            el.style.top = y + (units ? units : 'px');
        },

        // Set the content of the element identified by its id
        setContent: function (el, content) {
            if (util.isString(el)) {
                el = this.getById(el);
            }

            el.innerHTML = content;
        },

        // Return the html content of the element identified by its id
        getContent: function (el) {
            if (util.isString(el)) {
                el = this.getById(el);
            }

            return el.innerHTML;
        },

        setAttribute: function (el, name, value) {
            if (util.isString(el)) {
                el = this.getById(el);
            }

            el.setAttribute(name, value);
        },

        // Adds an event handler
        on: function (el, evt, callback) {
            if (util.isString(el)) {
                el = this.getById(el);
            }

            el.addEventListener(evt, callback, false);
        },

        // Removes the event identified by evt or if non is provided it removes all
        off: function (el, evt, callback) {
            if (util.isString(el)) {
                el = this.getById(el);
            }

            el.removeEventListener(evt, callback, false);
        },

        // Removes the element identified by id from the DOM
        remove: function (el) {
            if (util.isString(el)) {
                el = this.getById(el);
            }

            el.parentNode.removeChild(el);
        }
    };

});